/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
  <file> uls_istream.h </file>
  <brief>
    The procedures manipulating input(fd,str).
    This file is part of ULS, Unified Lexical Scheme.
  </brief>
  <author>
    Stanley J. Hong <babel96@gmail.com>, 2011.
  </author>
*/

#ifndef __ULS_ISTREAM_H__
#define __ULS_ISTREAM_H__

#include "uls_const.h"
#include "istr_fd.h"

#ifdef __cplusplus
extern "C" {
#endif

struct _uls_token {
	int  id;
	uls_char_t *text;
	int  len_text;
	int  offset;
};

struct _uls_literal {
	int  tok_id;
	int  offset1;
	int  len1;
	uls_char_t *text;
	int  len_text;
	int  offset2;
	int  n_lfs;
};

#define ULS_WANT_EOF_TOK      0x0001

struct _istr_context {
	uls_flags_t flags;

	uls_char_t *tag;
	int  tag_siz;
	int  lineno;

	istr_fd_t  fd_source;

	//
	//  lptr will traverse [line, ..., line_end)
	//
	uls_char_t *line, *lptr, *line_end;

	uls_literal_t literals[ULS_ISTR_LITERALS_MAX+1];
	int        i_literals, n_literals;

	uls_token_t  *tok_tower;
	int  tok_tower_len, tok_tower_siz;

	uls_char_t       *cstr_pool;
	int        cstr_pool_len, cstr_pool_siz;

	uls_gettok_t  gettok;
	istr_filler_t fill_proc;

	istr_commtype_t *last_end_mark;
	istr_context_t *prev;
};

struct _istr_commtype {
	uls_char_t start_mark[ULS_COMM_MARK_MAXSIZ+1];
	int  len_start_mark;
	uls_char_t end_mark[ULS_COMM_MARK_MAXSIZ+1];
	int  len_end_mark;
	int  n_lfs;
};

struct _istr_quotetype {
	uls_char_t name[ULS_LEXSTR_MAXSIZ+1];
	int  tok_id;

	uls_char_t start_mark[ULS_QUOTE_MARK_MAXSIZ+1];
	int  len_start_mark;
	uls_char_t end_mark[ULS_QUOTE_MARK_MAXSIZ+1];
	int  len_end_mark;

	istr_analyzer_t literal_analyzer;
};

struct _uls_istream {
	uls_char_t    ch_context[ULS_SYNTAX_TABLE_SIZE];

	istr_context_t fd_context;

	istr_commtype_t commtypes[ULS_N_MAX_COMMTYPES];
	int n_commtypes;

	istr_quotetype_t quotetypes[ULS_N_MAX_COMMTYPES];
	int n_quotetypes;
};

void uls_istr_init(uls_istream_t* istr);
void uls_istr_reset(uls_istream_t* istr);
void uls_istr_deinit(uls_istream_t* istr);

void istr_context_init(istr_context_t *istr_ctx, int fd);
void istr_context_deinit(istr_context_t *istr_ctx);
void istr_context_reset(istr_context_t *istr_ctx, int fd);
istr_context_t* istr_context_create(int fd);
void istr_context_destroy(istr_context_t *istr_ctx);

istr_context_t* export_istr_context(uls_istream_t* istr);
void import_istr_context(istr_context_t *istr_ctx, uls_istream_t* istr);

void uls_istr_change_filler(uls_istream_t* istr, istr_filler_t proc);
void uls_istr_set_tag(uls_istream_t* istr, const char* tagstr, int lno);
void uls_istr_inc_lineno(uls_istream_t* istr, int delta);
void uls_istr_set_line(uls_istream_t* istr, char* line, int len);
int uls_istr_left_bytes(uls_istream_t* istr);

istr_quotetype_t* find_quotetype_by_tokid(
	istr_quotetype_t *quotetypes, int n_quotetypes, int tok_id);
uls_char_t* istr_quotetype_start_mark(uls_istream_t* istr, int tok_id);

istr_quotetype_t* istr_find_quotetype(uls_istream_t* istr, uls_char_t *ptr, int len);
int istr_delete_lit_analyzer(uls_istream_t* istr, const uls_char_t* prefix);
int istr_change_lit_analyzer(uls_istream_t* istr, const uls_char_t* prefix, istr_analyzer_t lit_analyzer);

int default_fillproc(uls_istream_t* istr,
	uls_char_t** p_line, uls_literal_t* lits, int* n_lits);

int verbatim_lit_analyzer(istr_fd_t *fd_src, uls_char_t* quote_str, csz_str_t *ss_dst, uls_literal_t* lit, int* p_lno);
int default_lit_analyzer(istr_fd_t *fd_src, uls_char_t* quote_str, csz_str_t *ss_dst, uls_literal_t* lit, int* p_lno);
int wchar_lit_analyzer(istr_fd_t *fd_src, uls_char_t* quote_str, csz_str_t *ss_dst, uls_literal_t* lit, int* p_lno);

#ifdef __cplusplus
}
#endif

#endif
